import axios, { InternalAxiosRequestConfig, AxiosResponse } from 'axios';
import { useNavigate, useLocation } from 'react-router-dom';
import { useRef } from 'react';

import { useUserStore } from '@/store';
import { error as messageError } from '@/service/app/useMessage';
import { warning as modelWarning } from '@/service/app/useModal';

let tipIsShou = false; // 提示是否在开启

const errorCode: Record<string, string> = {
    401: '认证失败，无法访问系统资源',
    403: '当前操作没有权限',
    404: '访问资源不存在',
    default: '网络信号差，请稍后再试'
};

// 创建 axios 实例
export const service = axios.create({
    baseURL: import.meta.env.VITE_APP_BASE_API,
    timeout: 60000,
    headers: { 'Content-Type': 'application/json;charset=utf-8' }
});

const fitlerUtf8mb4 = (str: any) => {
    let newStr = '';
    for (const c of str) {
        if (c.codePointAt(0) <= 65535) {
            newStr += c;
        }
    }
    return newStr;
};
const filterObject = (data: any) => {
    const dataType = Object.prototype.toString.call(data);
    if (dataType === '[object Object]') {
        const keys = Object.keys(data);
        keys.forEach((key) => {
            const value = data[key];
            const valueType = Object.prototype.toString.call(value);
            if (valueType === '[object Object]') {
                filterObject(value);
            } else if (valueType === '[object Array]') {
                value.forEach((item: any) => {
                    filterObject(item);
                });
            } else if (valueType === '[object String]') {
                data[key] = fitlerUtf8mb4(value);
            }
        });
    } else if (dataType === '[object Array]') {
        data.forEach((item: any) => {
            filterObject(item);
        });
    }
};

let interceptorsNeedSet = true;

export const resetInterceptorsNeedSet = () => {
    interceptorsNeedSet = true;
}

export const useHttpInterceptor = () => {
    const navigate = useNavigate();
    const location = useLocation();

    const pathnameRef = useRef(location.pathname);
    const navigateRef = useRef(navigate);

    if (interceptorsNeedSet) {
        // 为了立即设置拦截器所以不放到useEffect中
        console.log('设置request拦截了')
        service.interceptors.request.clear();
        service.interceptors.response.clear();
        // 请求拦截器
        service.interceptors.request.use(
            (config: InternalAxiosRequestConfig) => {
                // 是否需要设置 token
                const isToken = (config.headers || {}).isToken === false;
                const token = useUserStore.getState().token
                if (token && !isToken) {
                    config.headers && (config.headers.token = token); // 让每个请求携带自定义token 请根据实际情况自行修改
                }
                // get请求映射params参数
                if (config.method === 'get' && config.params) {
                    let url = `${config.url}?`;
                    filterObject(config.params);
                    // Object.keys(config.params).forEach(propName => {
                    //     const value = config.params[propName];
                    //     const part = `${encodeURIComponent(propName)}=`;
                    //     if (value !== null && typeof value !== 'undefined') {
                    //         if (typeof value === 'object') {
                    //             Object.keys(value).forEach(key => {
                    //                 const params = `${propName}[${key}]`;
                    //                 const subPart = `${encodeURIComponent(params)}=`;
                    //                 url += `${subPart + encodeURIComponent(value[key])}&`;
                    //             });
                    //         } else {
                    //             url += `${part + encodeURIComponent(value)}&`;
                    //         }
                    //     }
                    // });
                    url = url.slice(0, -1);
                    config.params = {};
                    config.url = url;
                }
                if (config.method == 'post') {
                    filterObject(config.data);
                }
                return config;
            },
            (error) => {
                //console.log(1,error);
                Promise.reject(error);
            }
        );

        // 响应拦截器
        service.interceptors.response.use(
            (res: AxiosResponse) => {
                //console.log(82,res)
                // 未设置状态码则默认成功状态
                const code = res.data.code || 0;
                if (code !== 0) {
                    if (code === -1) {
                        navigateRef.current(`/login?redirect=`);
                        return Promise.reject(res);
                    }
                    messageError({
                        content: res.data.msg
                    });
                    return Promise.reject(res);
                }
                return res;
            },
            (error) => {
                const msg =
                    (error.response.data && error.response.data.msg) ||
                    errorCode[error.response.status] ||
                    errorCode.default;
                if (error.response.status === 401) {
                    if (error.config.url === '/admin/api/login/logout') return; // 登出接口返回401不弹出重新登录框
                    if (pathnameRef.current !== '/login') {
                        if (tipIsShou) return;
                        tipIsShou = true;
                        modelWarning({
                            content: msg,
                            title: '系统提示',
                            okText: '重新登录',
                            cancelText: '取消',
                            onOk() {
                                // 登出操作
                            },
                            onCancel() {},
                            afterClose() {
                                tipIsShou = false;
                            }
                        });
                    }
                } else {
                    messageError({
                        content: msg
                    });
                }
                return Promise.reject(error);
            }
        );
        interceptorsNeedSet = false;
    }
};
